﻿// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <tlhelp32.h>
#include <Psapi.h>
#include <bcrypt.h>
#include <exception>

extern "C" __declspec(dllexport) ULONGLONG GetTotalPhysMem();
extern "C" __declspec(dllexport) ULONGLONG GetUsedPhysMem();

extern "C" __declspec(dllexport) BOOL TryElevatePrivileges();

extern "C" __declspec(dllexport) int CleanProcessWorkingSet(); //遍历所有进程，并尝试清空它们的工作集。
extern "C" __declspec(dllexport) int CleanProcessWorkingSet2();//使用NtSetSystemInformation强制清空所有进程的工作集

extern "C" __declspec(dllexport) int FlushSystemBuffer();//清理系统缓存
extern "C" __declspec(dllexport) int DeepCleanMemory();  //使用所有已知手段深度清理



enum _SYSTEM_INFORMATION_CLASS { // info param 1
    SystemFileCacheInformation = 0x15, // 查询系统缓存用
    SystemMemoryListInformation = 0x50, // rammap用的，可清理sguard   6.0 and higher
    SystemCombinePhysicalMemoryInformation = 0x82, // memreduct 1   6.2 and higher
};

enum _SYSTEM_MEMORY_LIST_COMMAND { // info param 2
    MemoryCaptureAccessedBits,
    MemoryCaptureAndResetAccessedBits,
    MemoryEmptyWorkingSets, // rammap用的
    MemoryFlushModifiedList, // 新加的
    MemoryPurgeStandbyList,
    MemoryPurgeLowPriorityStandbyList, // 新加的
    MemoryCommandMax
};
using NtSetSystemInformation_t = NTSTATUS(WINAPI*)(INT, PVOID, ULONG);
using NtQuerySystemInformation_t = DWORD(WINAPI*)(UINT, PVOID, DWORD, PDWORD);

typedef struct _MEMORY_COMBINE_INFORMATION_EX { // info param 2
    HANDLE    Handle;
    ULONG_PTR PagesCombined;
    ULONG     Flags;
} MEMORY_COMBINE_INFORMATION_EX;

typedef struct _SYSTEM_FILECACHE_INFORMATION { // info param 2
    SIZE_T CurrentSize;
    SIZE_T PeakSize;
    ULONG  PageFaultCount;
    SIZE_T MinimumWorkingSet;
    SIZE_T MaximumWorkingSet;
    SIZE_T CurrentSizeIncludingTransitionInPages;
    SIZE_T PeakSizeIncludingTransitionInPages;
    ULONG  TransitionRePurposeCount;
    ULONG  Flags;
} SYSTEM_FILECACHE_INFORMATION;


NtSetSystemInformation_t         NtSetSystemInformation;
NtQuerySystemInformation_t       NtQuerySystemInformation;

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

int CleanProcessWorkingSet() {
    HANDLE            hSnapshot = NULL;
    PROCESSENTRY32    pe = {};
    pe.dwSize = sizeof(PROCESSENTRY32);


    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) {
        return 1;
    }

    for (BOOL next = Process32First(hSnapshot, &pe); next; next = Process32Next(hSnapshot, &pe)) {
        //遍历快照中的所有进程。
        try
        {
            auto handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_SET_QUOTA, FALSE, pe.th32ProcessID);
            //尝试以特定权限打开进程。
            if (!handle) {
                handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_SET_QUOTA, FALSE, pe.th32ProcessID);
            }
            if (!handle) {
                continue;
            }
            if (!EmptyWorkingSet(handle)) { //尝试清空进程的工作集。
                //MessageBox(0, "EmptyWorkingSet false", 0, 0);
            }
            CloseHandle(handle);
        }
        catch (const std::exception&)
        {

        }
        
    }
    CloseHandle(hSnapshot);
    return 0;
}

int CleanProcessWorkingSet2() {
    if (!NtSetSystemInformation) {
        if (auto hNtdll = GetModuleHandle(L"ntdll.dll")) {
            NtSetSystemInformation = (NtSetSystemInformation_t)GetProcAddress(hNtdll, "NtSetSystemInformation");
            NtQuerySystemInformation = (NtQuerySystemInformation_t)GetProcAddress(hNtdll, "NtQuerySystemInformation");
            // 从ntdll.dll获取NtSetSystemInformation和NtQuerySystemInformation函数的地址。  
            // 注意：这些函数是未公开的，直接调用它们可能会导致应用程序与不同版本的Windows不兼容。  
        }
        else {
            return 1;
        }
    }

    //这个函数使用 NtSetSystemInformation 函数清空所有进程的工作集。
    if (!NtSetSystemInformation) {
        return 2;
    }

    _SYSTEM_MEMORY_LIST_COMMAND command = MemoryEmptyWorkingSets; //设置命令为清空工作集。

    if (NtSetSystemInformation(SystemMemoryListInformation, &command, sizeof(command)) >= 0) //执行命令
        return 0;
    else
        return 3;
}

int FlushSystemBuffer() {
    if (!NtSetSystemInformation) {
        if (auto hNtdll = GetModuleHandle(L"ntdll.dll")) {
            NtSetSystemInformation = (NtSetSystemInformation_t)GetProcAddress(hNtdll, "NtSetSystemInformation");
            NtQuerySystemInformation = (NtQuerySystemInformation_t)GetProcAddress(hNtdll, "NtQuerySystemInformation");
            // 从ntdll.dll获取NtSetSystemInformation和NtQuerySystemInformation函数的地址。  
            // 注意：这些函数是未公开的，直接调用它们可能会导致应用程序与不同版本的Windows不兼容。  
        }
        else {
            return 1;
        }
    }

    if (!NtSetSystemInformation) {
        return 2;
    }

    SYSTEM_FILECACHE_INFORMATION info;
    ZeroMemory(&info, sizeof(info)); //初始化文件缓存信息结构。
    info.MinimumWorkingSet = -1;
    info.MaximumWorkingSet = -1; //设置最小和最大工作集大小为无效值，以触发缓存清空。

    if (NtSetSystemInformation(SystemFileCacheInformation, &info, sizeof(info)) >= 0) { //执行命令
        return 0;
    }
    else
    {
        return 3;
    }
}

int DeepCleanMemory() {
    if (!NtSetSystemInformation) {
        if (auto hNtdll = GetModuleHandle(L"ntdll.dll")) {
            NtSetSystemInformation = (NtSetSystemInformation_t)GetProcAddress(hNtdll, "NtSetSystemInformation");
            NtQuerySystemInformation = (NtQuerySystemInformation_t)GetProcAddress(hNtdll, "NtQuerySystemInformation");
            // 从ntdll.dll获取NtSetSystemInformation和NtQuerySystemInformation函数的地址。  
            // 注意：这些函数是未公开的，直接调用它们可能会导致应用程序与不同版本的Windows不兼容。  
        }
        else {
            return 1;
        }
    }

    if (!NtSetSystemInformation) {
        //检查NtSetSystemInformation函数指针是否被正确解析或赋值。如果该函数指针为NULL（即未解析或赋值），则函数立即返回，不执行任何操作。
        // 这是因为NtSetSystemInformation是一个未公开的函数，需要通过某些手段（如逆向工程）获取其地址。
        return 2;
    }
    try
    {
        // combine memory needs nt >= 6.2 (win 8+).
        MEMORY_COMBINE_INFORMATION_EX combine;
        ZeroMemory(&combine, sizeof(combine));
        //这个结构体用于指示系统合并物理内存信息，这在Windows 8及更高版本中支持。
        NtSetSystemInformation(SystemCombinePhysicalMemoryInformation, &combine, sizeof(combine));
        //尝试合并物理内存。这一操作可能有助于优化内存使用，但也可能导致系统不稳定。

        // system working set
        SYSTEM_FILECACHE_INFORMATION info;
        ZeroMemory(&info, sizeof(info));
        //这个结构体用于控制文件缓存的工作集大小。
        info.MinimumWorkingSet = -1;
        info.MaximumWorkingSet = -1;
        //将info结构体中的MinimumWorkingSet和MaximumWorkingSet成员设置为 - 1，这通常表示禁用或忽略这些限制。
        NtSetSystemInformation(SystemFileCacheInformation, &info, sizeof(info));
        //尝试设置文件缓存的工作集大小。

        // working set
        _SYSTEM_MEMORY_LIST_COMMAND command = MemoryEmptyWorkingSets;
        NtSetSystemInformation(SystemMemoryListInformation, &command, sizeof(command));
        //尝试清空工作集
        // others are supported in nt >= 6.0 (vista+).

        // standby priority 0 list
        command = MemoryPurgeLowPriorityStandbyList;
        NtSetSystemInformation(SystemMemoryListInformation, &command, sizeof(command));
        //清除低优先级备用列表中的页面

        // standby list
        command = MemoryPurgeStandbyList;
        NtSetSystemInformation(SystemMemoryListInformation, &command, sizeof(command));
        //清除备用列表中的页面。

        // modified page list
        command = MemoryFlushModifiedList;
        NtSetSystemInformation(SystemMemoryListInformation, &command, sizeof(command));
        //刷新已修改页面列表，将其写入磁盘。

        //所有已知的这些操作，都是针对系统内存管理的低级操作，旨在释放或优化内存使用。
    }
    catch (const std::exception&)
    {
        return 3;
    }
    return 0;
    
}

ULONGLONG GetTotalPhysMem() {
    MEMORYSTATUSEX memInfo;
    memset(&memInfo, 0, sizeof(memInfo));
    memInfo.dwLength = sizeof(MEMORYSTATUSEX);
    GlobalMemoryStatusEx(&memInfo);
    return memInfo.ullTotalPhys;
}

ULONGLONG GetUsedPhysMem() {
    MEMORYSTATUSEX memInfo;
    memset(&memInfo, 0, sizeof(memInfo));
    memInfo.dwLength = sizeof(MEMORYSTATUSEX);
    GlobalMemoryStatusEx(&memInfo);
    return memInfo.ullTotalPhys - memInfo.ullAvailPhys;
}

int TryElevatePrivileges() {
    HANDLE hToken;
    TOKEN_PRIVILEGES tp;
    int result = 9;
    try
    {
        // 打开当前进程的访问令牌  
        if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
        {
            ZeroMemory(&tp, sizeof(tp));
            tp.PrivilegeCount = 1;
            tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

            // 尝试提升“增加配额权限”  
            if (LookupPrivilegeValue(NULL, SE_INCREASE_QUOTA_NAME, &tp.Privileges[0].Luid))
            {//SE_INCREASE_QUOTA_NAME = SeIncreaseQuotaPrivilege
                if (AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL))
                {
                    // 检查是否成功提升权限（这里省略了PrivilegeCheck的实现）  
                    // ...（需要实现PrivilegeCheck或检查AdjustTokenPrivileges的返回值和GetLastError）  
                    result = 0; // 假设成功（实际上应该检查AdjustTokenPrivileges的返回值和错误码）  
                }
                else {
                    result = 1;
                }
            }
            else
            {
                result = 11;
            }
            if (0 == result) {
                if (LookupPrivilegeValue(NULL, SE_PROF_SINGLE_PROCESS_NAME, &tp.Privileges[0].Luid))
                {//SE_PROF_SINGLE_PROCESS_NAME = "SeProfileSingleProcessPrivilege"
                    if (AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL))
                    {
                        // 检查是否成功提升权限（这里省略了PrivilegeCheck的实现）  
                        // ...（需要实现PrivilegeCheck或检查AdjustTokenPrivileges的返回值和GetLastError）  
                        result = 0; // 假设成功（实际上应该检查AdjustTokenPrivileges的返回值和错误码）  
                    }
                    else {
                        result = 2;
                    }
                }
                else
                {
                    result = 12;
                }
            }

            BOOL bResult;
            PRIVILEGE_SET ps;
            
            if (0 == result) {
                ZeroMemory(&ps, sizeof(ps));
                if (LookupPrivilegeValue(NULL, SE_INCREASE_QUOTA_NAME, &tp.Privileges[0].Luid)) {
                    if (PrivilegeCheck(hToken, &ps, &bResult)) {
                        result = 0;
                    }
                    else {
                        result = 3;
                    }
                }
                else
                {
                    result = 13;
                }
            }
            if (0 == result) {
                ZeroMemory(&ps, sizeof(ps));
                if (LookupPrivilegeValue(NULL, SE_PROF_SINGLE_PROCESS_NAME, &ps.Privilege[0].Luid)) {
                    if (PrivilegeCheck(hToken, &ps, &bResult)) {
                        result = 0;
                    }
                    else {
                        result = 4;
                    }
                }
                else
                {
                    result = 14;
                }
            }
            // 关闭句柄  
            CloseHandle(hToken);
        }
    }
    catch(const std::exception&)
    {
        CloseHandle(hToken);
    }
  
    return result;
}

